﻿using Basic.HrCollect;
using Basic.HrModel.Emp;
using Basic.HrModel.Msg;
using Basic.HrRemoteModel.Msg.Model;
using Basic.HrService.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;
using WeDonekRpc.Model;

namespace Basic.HrService.lmpl
{
    internal class EmpMsgService : IEmpMsgService
    {
        private readonly IEmpMsgListCollect _Msg;
        private readonly IEmpCollect _Emp;
        private readonly IDeptCollect _Dept;
        private readonly IDicItemCollect _DictItem;
        private readonly IHrConfig _Config;

        public EmpMsgService ( IEmpMsgListCollect msg,
            IEmpCollect emp,
            IDicItemCollect dictItem,
            IDeptCollect dept,
            IHrConfig config )
        {
            this._Dept = dept;
            this._Msg = msg;
            this._Emp = emp;
            this._DictItem = dictItem;
            this._Config = config;
        }
        public Dictionary<string, int> GetTotal ( MsgGetArg arg )
        {
            return this._Msg.GetMsgTotal(arg);
        }
        public void Adds ( MsgAdd add )
        {
            this._Msg.Adds(add);
        }

        public PagingResult<MsgDatum> Query ( MsgQuery query, IBasicPage paging )
        {
            MsgDto[] dtos = this._Msg.Query<MsgDto>(query, paging, out int count);
            if ( dtos.IsNull() )
            {
                return new PagingResult<MsgDatum>();
            }
            long[] empId = dtos.ConvertAll(a => a.FormEmpId);
            Dictionary<string, string> itemText = this._DictItem.GetTexts(this._Config.MsgClassifyDicId, dtos.Distinct(a => a.MsgClassify));
            EmpDto[] emps = this._Emp.Gets<EmpDto>(empId);
            List<long> deptId = new List<long>();
            emps.ForEach(c =>
            {
                deptId.Add(c.UnitId);
                deptId.Add(c.DeptId);
            });
            Dictionary<long, string> dept = this._Dept.GetDeptName(deptId.Distinct().ToArray());
            return new PagingResult<MsgDatum>(dtos.ConvertAll(a =>
            {
                EmpDto emp = emps.Find(c => c.EmpId == a.FormEmpId);
                return new MsgDatum
                {
                    Id = a.Id,
                    AddTime = a.AddTime,
                    Attrs = a.Attrs,
                    Body = a.Body,
                    LinkPk = a.LinkPk,
                    MsgType = a.MsgType,
                    MsgStatus = a.MsgStatus,
                    LinkType = a.LinkType,
                    Tag = a.Tag,
                    Classify = itemText.GetValueOrDefault(a.MsgClassify),
                    FormEmp = new MsgEmp
                    {
                        Dept = dept.GetValueOrDefault(emp.UnitId) + " " + dept.GetValueOrDefault(emp.DeptId),
                        EmpHead = emp.UserHead,
                        Sex = emp.Sex,
                        EmpId = emp.EmpId,
                        EmpName = emp.EmpName,
                        EmpNo = emp.EmpNo
                    },
                    IsRead = a.IsRead,
                    MsgTitle = a.MsgTitle,
                    Priority = a.Priority,
                    TimeOut = a.TimeOut,
                };
            }), count);
        }

        public void SetDone ( string linkType, long linkPk, string tag )
        {
            EmpMsgDto msg = this._Msg.Get<EmpMsgDto>(linkType, linkPk, tag);
            if ( msg.MsgType != HrRemoteModel.HrMsgType.待办消息 )
            {
                throw new ErrorException("hr.msg.type.error");
            }
            _ = this._Msg.SetAlreadyDo(msg);
        }

        public void SetAlreadyRead ( long id )
        {
            EmpMsgDto msg = this._Msg.Get<EmpMsgDto>(id);
            _ = this._Msg.SetAlreadyRead(msg);
        }

        public void SetAlreadyRead ( long[] ids )
        {
            this._Msg.SetAlreadyRead(ids);
        }

        public void ToVoid ( ToVoidItem[] items )
        {
            long[] msgId = this._Msg.GetWaitToVoidMsgId(items);
            if ( !msgId.IsNull() )
            {
                this._Msg.ToVoidMsg(msgId);
            }
        }

        public void ToVoid ( string linkType, long linkPk, string tag )
        {
            this._Msg.ToVoidMsg(linkType, linkPk, tag);
        }

        public void BatchOpt ( MsgAdd[] adds, ToVoidItem[] toVoid, MsgItem[] done )
        {
            BatchOpt opt = new BatchOpt
            {
                Adds = adds
            };
            if ( !toVoid.IsNull() )
            {
                opt.ToVoidId = this._Msg.GetWaitToVoidMsgId(toVoid);
            }
            if ( !done.IsNull() )
            {
                opt.DoneId = this._Msg.GetMsgId(done);
            }
            this._Msg.Save(opt);
        }
    }
}
